﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lidgren.Network;
using System.Threading;
using SharedLib.Engine;
using Microsoft.Xna.Framework;

namespace SharedLib.Network.Server
{
    public class Server
    {
        public static Server Instance;

        public NetServer netServer;

        public Thread Listener;
        public ServerListener ServerListener;
        public ServerSender ServerSender;
        public ServerConsole Console;
        public ServerWorld GameWorld;
        public ServerEntitiesManager EntitiesManager;

        public bool KeepServerRunning = true;
        public bool RestartServer = false;

        private DateTime _lastKeyAvaible = DateTime.Now;

        

        public Server()
        {
            Instance = this;

            NetPeerConfiguration netConfig = new NetPeerConfiguration(Constants.REMOTE_SERVICE_NAME);
            netConfig.Port = Constants.REMOTE_PORT;
            netConfig.MaximumConnections = 10;
            netConfig.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
            netConfig.DisableMessageType(NetIncomingMessageType.UnconnectedData);

            EntitiesManager = new ServerEntitiesManager(this);

            netServer = new NetServer(netConfig);
            GameWorld = new ServerWorld(this);
            Console = new ServerConsole(this);
            ServerListener = new ServerListener(netServer, this);
            ServerSender = new ServerSender(netServer, this);

            

            Listener = new Thread(ServerListener.Start);

            for (int i = 0; i < 1000; i++)
            {
                ServerChunk c = GameWorld.Chunks.ElementAt(Constants.Random.Next(0, GameWorld.Chunks.Count));
                Int32 x = Constants.Random.Next(0, Constants.CHUNK_WIDTH);
                Int32 y = Constants.Random.Next(0, Constants.CHUNK_HEIGHT);

                Monster mob = new Monster();
                mob.ID = IDManager.getNewID();
                mob.Position = new Vector2(c.X * Constants.CHUNK_WIDTH * Constants.TILE_SIZE + Constants.TILE_SIZE * x, c.Y * Constants.CHUNK_HEIGHT * Constants.TILE_SIZE + Constants.TILE_SIZE * y);
                mob.HP = 100;
                mob.HPMAX = 100;
                mob.Mana = 100;
                mob.ManaMAX = 100;
                mob.Name = "testmob"+i.ToString();

               EntitiesManager.EntitiesList.Add(mob.ID, mob);
            }

            for (int i = 0; i < 1000; i++)
            {
                ServerChunk c = GameWorld.Chunks.ElementAt(Constants.Random.Next(0, GameWorld.Chunks.Count));
                Int32 x = Constants.Random.Next(0, Constants.CHUNK_WIDTH);
                Int32 y = Constants.Random.Next(0, Constants.CHUNK_HEIGHT);

                Light maLumiere = new Light();
                maLumiere.Intensity = 1f;
                maLumiere.ID = IDManager.getNewID();
                maLumiere.Position = new Vector2(c.X * Constants.CHUNK_WIDTH * Constants.TILE_SIZE + Constants.TILE_SIZE * x, c.Y * Constants.CHUNK_HEIGHT * Constants.TILE_SIZE + Constants.TILE_SIZE * y);
                maLumiere.Fov = (float)Math.PI * 2;
                maLumiere.Range = Convert.ToInt16( Constants.Random.Next(250,800));
                maLumiere.Rotation = 0;
                maLumiere.R = (byte)Constants.Random.Next(100,255);
                maLumiere.G = (byte)Constants.Random.Next(100, 255);
                maLumiere.B = (byte)Constants.Random.Next(100, 255);
                EntitiesManager.EntitiesList.Add(maLumiere.ID, maLumiere);
            }

            
        }

        public void Start()
        {
            Console.SetTitle(Constants.APP_NAME + " Server - v " + Constants.SERVER_VERSION);

            LoadSettings();


            netServer.Start();
            Listener.Start();

            Console.ConsoleWrite("Server started", ConsoleColor.Green);
            while (KeepServerRunning)
            {
                while (Console.KeyAvailable())
                {
                    TimeSpan timeSpanLastKeyAvaible = DateTime.Now - _lastKeyAvaible;
                    if (timeSpanLastKeyAvaible.Milliseconds < 2000)
                    {
                        string input = Console.ReadLine();
                        Console.ProcessInput(input);
                        _lastKeyAvaible = DateTime.Now;
                        break;
                    }
                }
            }
        }

        public void LoadSettings()
        {
            netServer.Configuration.MaximumConnections = 10;

        }
    }
}
